/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package arbol_sintactico_abstracto;

import analizadorlexico.Token;
import generador_de_codigo.GeneradorDeCodigo;
import java.io.IOException;
import tabla_de_simbolos.Atributo;
import tabla_de_simbolos.Clase;
import tabla_de_simbolos.Constructor;
import tabla_de_simbolos.ErrorSemantico;
import tabla_de_simbolos.Metodo;
import tabla_de_simbolos.TablaDeSimbolos;
import tabla_de_simbolos.Tipo;

/**
 *
 * @author Javi
 */
public class For extends Sentencia {
    private Asignacion asig;
    private Expresion exp1, exp2;
    private Sentencia sent;

    public For(Token token, Asignacion asig, Expresion exp1, Expresion exp2, Sentencia sent) {
        this.token = token;
        this.asig = asig;
        this.exp1 = exp1;
        this.exp2 = exp2;
        this.sent = sent;
    }
    
    @Override
    public Tipo check(Clase clase, Constructor metodo, TablaDeSimbolos ts) throws ErrorSemantico, IOException {
        String etiqueta1 = GeneradorDeCodigo.generarEtiqueta("for");
        String etiqueta2 = GeneradorDeCodigo.generarEtiqueta("finfor");
        
        Tipo t_asig = asig.check(clase, metodo,ts);        
         GeneradorDeCodigo.generar(etiqueta1 + ": ");
        Tipo t_exp1 = exp1.check(clase, metodo,ts);               
       
        if(!t_exp1.getNombre().equals("boolean"))
            throw new ErrorSemantico("Sentencia for, se esperaba expresion booleana. Linea: "+ token.getLinea());
        
        GeneradorDeCodigo.generar("BF " + etiqueta2 + "\n");
                       
        sent.check(clase, metodo,ts);
        //ver porque sino deja un valor en tope de la pila que se consumira
        //luego por BF de arriba dado q no hay una expresion que cambie el valor de la variable de control en asig
        Tipo t_exp2 = exp2.check(clase, metodo,ts);    
        
        if(!t_exp2.conforma(t_asig))
            throw new ErrorSemantico("Sentencia for, el tipo de la expresion 2 ('" + t_exp2.getNombre()+ "') no se corresponde con el tipo de la variable de control ('"+t_asig.getNombre()+"'). Linea: " + token.getLinea());
        
        asignar_variable_control(metodo,clase);
        
        GeneradorDeCodigo.generar("JUMP " + etiqueta1 + "\n");
        GeneradorDeCodigo.generar(etiqueta2 + ": ");
        
        return null;
    }

    private void asignar_variable_control(Constructor metodo, Clase clase) throws IOException {
        Token ladoIzq = asig.getLadoIzq();
        Tipo tipoIzq = null;
        int offset;
        for(Atributo param : metodo.getParametros()){
            if(param.getNombre().equals(ladoIzq.getLexema())){
                tipoIzq = param.getTipo();
                if(((Metodo)metodo).getModMetodo().getModificador().equals("dynamic"))
                    offset = metodo.getOffsetParam() - param.getOffset() + 3;
                else
                    offset = metodo.getOffsetParam() - param.getOffset() + 2;
                
                GeneradorDeCodigo.generar("STORE " + offset + "\n");
                break;
            }            
        }
        
        if(tipoIzq == null){
            for(Atributo var : metodo.getVariables()){
                if(var.getNombre().equals(ladoIzq.getLexema())){
                    tipoIzq = var.getTipo();
                    offset = var.getOffset();
                    GeneradorDeCodigo.generar("STORE " + offset + "\n");
                    break;
                }            
            }            
        }
        
        if(tipoIzq == null){
            for(Atributo var : clase.getListaAtributos()){
                if(var.getNombre().equals(ladoIzq.getLexema())){
                    tipoIzq = var.getTipo();
                    offset = var.getOffset();
                    GeneradorDeCodigo.generar("LOAD 3 \n");
                    GeneradorDeCodigo.generar("SWAP \n");
                    GeneradorDeCodigo.generar("STOREREF " + offset + "\n");
                    break;
                }            
            }            
        }
    }
}
